home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
mint
/
mint96sb.zoo
/
doc
/
filesys.doc
< prev
next >
Wrap
Text File
|
1992-09-09
|
35KB
|
723 lines
MiNT File Systems
MiNT allows loadable file systems, which means that it should be quite
easy to implement networked file systems, dynamically re-sizable ram
disks, or other nifty things (for example, Stephen Henson's minix.xfs
file system allows access to Minix partitions from TOS). Writing
these is not difficult, but there are a lot of data structures that
must be understood first. (These data structures are given in the
file "filesys.h".)
A note on conventions: a declaration like:
short foo P_((char *bar, long baz));
means that "foo" is a function that returns a 16 bit integer, and that
expects a pointer to a character and a 32 bit integer as its two
arguments. "ushort" is an unsigned 16 bit integer; "ulong" is an
unsigned 32 bit integer.
File Cookies
Files and directories are represented in the kernel by "cookies".
The contents of the cookie are mostly file system dependent, i.e. the
kernel interprets only the "fs" and "dev" field of the cookie, and the
contents of the other fields may be used by a file system as it sees fit.
A file cookie has the following structure:
typedef struct f_cookie {
FILESYS *fs; /* file system that knows about this cookie */
ushort dev; /* device info (e.g. Rwabs device number) */
ushort aux; /* extra data that the file system may want */
long index; /* this+dev uniquely identifies a file */
} fcookie;
(The "FILESYS" data type is defined below.)
The interpretation of the "aux" field is entirely file system dependent. The
"index" field is not presently used by the kernel, but file systems
should (if possible) make this field uniquely identify a file or directory
on a device.
File System Structure
This is the structure that tells the kernel about the file system,
and gives the entry points for routines which the kernel can call in order
to manipulate files and directories. Note that actual input/output
operations are performed by a device driver; most file systems have just
one associated device driver, but some may have more. See the section on
device drivers for more information on these.
Unless otherwise specified, all of the functions should return 0 for
success and an appropriate (long negative) error code for failure. Also,
note that it is the kernel's responsibility to do all access checking;
the file system may assume that the file's permissions have been checked
and are compatible with the current process' uid and the operation
selected.
Parameters are passed to file system driver functions on the stack.
The file system drivers should preserve registers d2-d7 and a2-a7,
and return any results in register d0. Note that this may differ from
your compiler's default conventions (for example, Alcyon C preserves
only registers d3-d7 and a3-a7); in this case, an assembly language
wrapper will be necessary.
typedef struct filesys {
struct filesys *next;
This is a link to the next file system in the kernel's list. It will be
filled in by the kernel; the file system should leave it as NULL.
long fsflags;
These flags give some information about the file system. Currently, three
flags are defined:
#define FS_KNOPARSE 0x01 /* kernel shouldn't do parsing */
#define FS_CASESENSITIVE 0x02 /* file names are case sensitive */
#define FS_NOXBIT 0x04 /* if a file can be read, it can be executed */
Other bits may be defined in future releases of MiNT; for now all other
bits in this flag should be 0. Most file systems will have only the
FS_NOXBIT flag; networked file systems may have FS_KNOPARSE for
reasons of efficiency, and file systems that must be compatible with Unix
or similar specifications may be case sensitive and hence have FS_CASESENSITIVE
set.
long (*root) P_((short drv, fcookie *fc));
This is the entry point for a routine to find a file cookie for the root
directory of BIOS device "drv" (an integer in the range 0-31 inclusive).
This function is called by the kernel when initializing a drive; the kernel
will query each file system in turn for a file cookie representing the
root directory of the drive. If the file system recognizes the data on
the drive as being valid for a file system that it recognizes, it should
fill in the cookie pointed to by "fc" and return 0. Otherwise, it should
return a negative error code (EDRIVE is a good choice) to indicate that the
drive must belong to another file system. Note that this function is called
at boot up time and also at any time when media change is detected on a drive.
long (*lookup) P_((fcookie *dir, char *name, fcookie *fc));
Translate a file name into a cookie. "dir" is the cookie for a directory,
returned by a previous call to (*lookup) or (*root). "name" is either the
name of a file in that directory (if fsflags & FS_KNOPARSE == 0) or a path
name relative to that directory (if fsflags & FS_KNOPARSE == FS_KNOPARSE).
If the file is not found, an appropriate error code (like EFILNF) should be
returned. If the file is found, the cookie "*fc" should be filled in with
appropriate data, and either 0 or EMOUNT returned. EMOUNT should be returned
only if "name" is ".." and "dir" represents the root directory of a drive;
0 should be returned otherwise. Note that a lookup call with a null name
or with "." should always succeed and return a cookie representing the
directory itself. Also note that symbolic links should *never* be followed.
long (*creat) P_((fcookie *dir, char *name, ushort mode,
short attrib, fcookie *fc)
Create a new file named "name" in the directory whose cookie is "dir".
"mode" gives the file's type and access permissions, as follows:
/* file types */
#define S_IFMT 0170000 /* mask to select file type */
#define S_IFCHR 0020000 /* BIOS special file */
#define S_IFDIR 0040000 /* directory file */
#define S_IFREG 0100000 /* regular file */
#define S_IFIFO 0120000 /* FIFO */
#define S_IMEM 0140000 /* memory region or process */
#define S_IFLNK 0160000 /* symbolic link */
/* special bits: setuid, setgid, sticky bit */
#define S_ISUID 04000 /* change euid when executing this file */
#define S_ISGID 02000 /* change egid when executing this file */
#define S_ISVTX 01000 /* not implemented */
/* file access modes for user, group, and other*/
#define S_IRUSR 0400 /* read access for user */
#define S_IWUSR 0200 /* write access for user */
#define S_IXUSR 0100 /* execute access for user */
#define S_IRGRP 0040 /* ditto for group... */
#define S_IWGRP 0020
#define S_IXGRP 0010
#define S_IROTH 0004 /* ditto for everyone else */
#define S_IWOTH 0002
#define S_IXOTH 0001
"attrib" gives the standard TOS attribute byte. This is slightly redundant
with "mode" (i.e. the FA_RDONLY bit should agree with the settings of
S_IWUSR, S_IWGRP, and S_IWOTH, and FA_DIR should be set if and only if
the file's format is S_IFDIR) but is provided for convenience for standard
DOS compatible file systems.
The kernel will make the "creat" call only after using "lookup" in an attempt
to find the file. The file system should create the file (if possible) and
set the cookie pointed to by "fc" to represent the newly created file.
If an error of any sort occurs, an appropriate error number is returned,
otherwise 0 is returned. Also note that the kernel will not try to
create directories this way; it will use "mkdir" (q.v.) instead.
DEVDRV *(*getdev) P_((fcookie *fc, long *devspecial))
Get the device driver which should be used to do i/o on the file whose
cookie is "fc". If an error occurs, a NULL pointer should be returned
and an error code placed in the long pointed to by "devspecial"; otherwise,
"devspecial" should be set to a device-driver specific value which will
be placed by the kernel in the "devinfo" field of the FILEPTR structure
passed to the device driver's open routine. (The interpretation of
this value is a matter for the file system and the device driver, the
kernel doesn't care.)
If the call to (*getdev) succeeds, a pointer to a device driver structure
(see below) is returned; if it fails, a NULL pointer should be returned and
an appropri